/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


import java.util.Random;

import junit.framework.TestCase;





/**
 * Performs Validation Test for url validations.
 *
 * @version $Revision: 1128446 $ $Date: 2011-05-27 13:29:27 -0700 (Fri, 27 May 2011) $
 */
public class UrlValidatorTest extends TestCase {

   private boolean printStatus = false;
   private boolean printIndex = false;//print index that indicates current scheme,host,port,path, query test were using.

   public UrlValidatorTest(String testName) {
      super(testName);
   }

   
   
   public void testManualTest()
   {
	   UrlValidator urlVal = new UrlValidator(null, null, UrlValidator.ALLOW_ALL_SCHEMES);
//	   testResults(true , urlVal.isValid("http://www.amazon.com"), "http://www.amazon.com");
//	   testResults(true , urlVal.isValid("http://www.amazon.com/"), "http://www.amazon.com/");
//	   testResults(true , urlVal.isValid("http://www.amazon.com/test"), "http://www.amazon.com/test");
//	   testResults(false, urlVal.isValid("http://www..amazon.com"), "http://www..amazon.com");
//	   testResults(false, urlVal.isValid("http://www.www.amazon.com"), "http://www.www.amazon.com");
//	   testResults(false, urlVal.isValid("http://www.amazon.com.com"), "http://www.amazon.com.com");
//	   testResults(false, urlVal.isValid("http://www.www.amazon.com.com"), "http://www.www.amazon.com.com");
//	   testResults(false, urlVal.isValid("http://ccc.amazon.com"), "http://ccc.amazon.com");
//	   testResults(false, urlVal.isValid("http://123.amazon.com"), "http://123.amazon.com");
//	   testResults(false, urlVal.isValid("http://1234.amazon.com"), "http://1234.amazon.com");
//	   testResults(false, urlVal.isValid("http:www.amazon.com"), "http:www.amazon.com");
//	   testResults(false, urlVal.isValid("://www.amazon.com"), "://www.amazon.com");
//	   testResults(false, urlVal.isValid("www.amazon.com"), "www.amazon.com");
//	   testResults(false, urlVal.isValid("amazon.com"), "amazon.com");
//	   testResults(false, urlVal.isValid("amazon"), "amazon");
//	   testResults(true , urlVal.isValid("http://www.amazon.cc"), "http://www.amazon.cc");
//	   testResults(false, urlVal.isValid("http://www.amazon.qqq"), "http://www.amazon.qqq");
//	   testResults(false, urlVal.isValid("http://www.qqq.com/http://www.amazon.com"), "http://www.qqq.com/http://www.amazon.com");
//	   testResults(false, urlVal.isValid("http://www.amazon.com/test.php?test=1"), "http://www.amazon.com/test.php?test=1");
//	   testResults(false, urlVal.isValid("http:///www.amazon.com/"), "http:///www.amazon.com/");
//	   testResults(false, urlVal.isValid("https:///www.amazon.com/"), "https:///www.amazon.com/");
//	   testResults(true , urlVal.isValid("https://www.amazon.com/"), "https://www.amazon.com/");
//	   testResults(true , urlVal.isValid("http://test.new.test1.test2.test3.test4.amazon.com/"), "http://test.new.test1.test2.test3.test4.amazon.com/");
//	   testResults(false, urlVal.isValid("http://?!\\.amazon.com"), "http://?!\\.amazon.com");
//	   testResults(true , urlVal.isValid("10.0.0.1"), "10.0.0.1");
//	   testResults(true , urlVal.isValid("http://10.0.0.1"), "http://10.0.0.1");
//	   testResults(true , urlVal.isValid("localhost"), "localhost");
//	   testResults(true , urlVal.isValid("localdomain"), "localdomain");
//	   testResults(true , urlVal.isValid("http://localhost.localdomain"), "http://localhost.localdomain");
//	   testResults(true , urlVal.isValid("https://xxx.xxx.com"), "https://xxx.xxx.com");
//	   testResults(true , urlVal.isValid("https://code.google.com/p/cs362s14/source/browse/#svn%2Ftrunk%2Fprojects%2Fchristia%253Fstate%253Dclosed"), "https://code.google.com/p/cs362s14/source/browse/#svn%2Ftrunk%2Fprojects%2Fchristia%253Fstate%253Dclosed");
//	   testResults(true , urlVal.isValid("https://www.com.arpa"), "https://www.com.arpa");
//	   testResults(false, urlVal.isValid("https://www.-com.arpa"), "https://www.-com.arpa");
//	   testResults(true , urlVal.isValid("ftp://google.com"), "ftp://google.com");
//	   testResults(true , urlVal.isValid("ftp://google.com/baz"), "ftp://google.com/baz");
//	   testResults(true , urlVal.isValid("http://www.amazon.com:50"), "http://www.amazon.com:50");
//	   testResults(true , urlVal.isValid("http://www.amazon.com:500"), "http://www.amazon.com:500");
//	   testResults(true , urlVal.isValid("http://www.amazon.com:5000"), "http://www.amazon.com:5000");
//	   testResults(true , urlVal.isValid("http://www.amazon.com:50000"), "http://www.amazon.com:50000");
//	   testResults(true,urlVal.isValid("https://flvmwa.jhqhgdwdhhltm.aero:25068"), "https://flvmwa.jhqhgdwdhhltm.aero:25068");
//	   testResults(true, urlVal.isValid("https://www.amazon.com:500"),"https://www.amazon.com:500");
   }
   
   /**
    * All websites have:
    * protocol://subdomain.domain.TLD
    * 
    * PROTOCOL - SPECIFIED LIST OF PROTOCOLS
    * DOMAINS - MORE OR LESS ANYTHING
    * SUBDOMAINS - MORE OR LESS ANYTHING 
    * PORTS - SPECIFIED LIST 
    * PATHS - FILESYSTEM LIST
    * QUERIES - SPECIFIC QUERIES test.php?parameter=1,asd=4
    * 
    * IP ADDRESSES - SPECIFIED RANGES
    * 
    */
   
   /**
    * test = PROTOCOL + <SUBDOMAINS> + <DOMAIN> + <TOP LEVEL DOMAIN> + <PORTS> + <PATHS> + <QUERIES>
    *
    * VALID:
    * RANDOM:
    * <SUBDOMAINS> ALPHANUM, <PORTS> NUM < 99999, <PATHS> ALHPANUM, <DOMAIN> 
    * 
    * FROM KNOWN LIST:
    * PROTOCOL, TOP LEVEL DOMAIN, STRUCTURED QUERIES
    * STRUCTURED QUERIES = ADDRESS + "?#:" + FILE + "=" + RANDOMSTUFF
    * RANDOM 4
    * SWITCH 1: ?
    * SWITCH 2: @ ... 
    *  
    * INVALID:
    * PORTS < 0 || > 99999, PATHS WITH INVALID PARAMETERS (!, >, \, :)
    * INCORRECT QUERIES (NOT INCLUDED IN LIST, RANDOMLY ASCII?)
    * 
    * test = <IP>.<IP>.<IP>.<IP>:<PORTS>
    * VALID:
    * <IP> <= 255
    * <PORTS> <= 99999
    * 
    * INVALID:
    * <IP> < 0 || > 255
    * <PORTS> < 0 || > 99999
    */
   
   /**
    * 
    * @param expected
    * @param actual
    * @param input
    */
   public void testResults(boolean expected, boolean actual, String input)
   {
	   if (expected != actual){
		   System.out.println("Fail - " + input + "   Expected - " + expected);
	   }
   }
   
   public void testYourFirstPartition()
   {
	   
   }
   
   public void testYourSecondPartition()
   {
	   
   }
   
   /**
    * Quite poor random tester
    * Randomly checks subdomains, domains, ports, paths and top level domains
    */
   public void testIsValid()
   {
	   UrlValidator urlVal = new UrlValidator(null, null, UrlValidator.ALLOW_ALL_SCHEMES);
	   Random r = new Random();
	   int failed = 0;
	   for(int i = 0;i<100;i++)
	   {
		   /* random: subdomains, ports, paths, domain */
		   int val = r.nextInt(15) + 1; // length of subdomains and domain
		   String domain = "";
		   for (int j = 0; j < val; j++)
		   {
			   int letter = (int)(r.nextInt(26) + 97);
			   domain = domain + (char)(letter);
		   }
		   val = r.nextInt(15) + 1; // length of subdomains and domain
		   
		   String subdomain = "";
		   for (int j = 0; j < val; j++)
		   {
			   int letter = (int)(r.nextInt(26) + 97); // random 
			   subdomain = subdomain + (char)(letter);
		   }
		   val = r.nextInt(2);
		   int port = 0;
		   if (val == 1) {
			   /* random ports */
			   port = r.nextInt(Integer.MAX_VALUE);
		   } else {
			   /* known ports */
			   port = r.nextInt(65000);
		   }
		   /* 1 in 100 chance for negative port */
		   int negative = r.nextInt(100);
		   if (negative == 1) {
			   port = -port;
		   }
		   val = r.nextInt(15) + 1; // path
		   
		   String path = "";
		   for (int j = 0; j < val; j++)
		   {
			   int letter = (int)(r.nextInt(26) + 97);
			   path = path + (char)(letter);
		   }
		   val = r.nextInt(15) + 1; // TLD
		   
		   String TLD = "";
		   for (int j = 0; j < val; j++)
		   {
			   int letter = (int)(r.nextInt(26) + 97);
			   TLD = TLD + (char)(letter);
		   }
		   /* use known protocols, for now */
		   String[] protocols = {"http", "ftp", "https"};
		   val = r.nextInt(3);

		   String testCase = protocols[val] + "://" + subdomain + "." + domain + ".";

		   /* selection of randomly known top level domains */
		   String[] TLDs = {"com", "net", "org", "aero"};
		   
		   /* randomly include ports */
		   int includePort = r.nextInt(2);
		   /* randomly include paths */
		   int includePath = r.nextInt(2);
		   /* 1 in 10 chance of using known top level domains */
		   int knownTLD = r.nextInt(10);
		   
		   if (knownTLD == 1) {
			   testCase = testCase + TLD;
		   } else {
			   val = r.nextInt(4);
			   testCase = testCase + TLDs[val];
		   }
		   if (includePort == 1) {
			 testCase = testCase + ":" + port;  
		   }
		   if (includePath == 1 && includePort != 1) {
			 testCase = testCase + "/" + path;  
		   }
		   if (!urlVal.isValid(testCase)) {
			   System.out.println(testCase);
			   failed++;
		   }
		   /* known: protocol, TLD. Queries */
	   }
	   System.out.println(failed);
   }
   
   public void testAnyOtherUnitTest()
   {
	   
   }
   /**
    * Create set of tests by taking the testUrlXXX arrays and
    * running through all possible permutations of their combinations.
    *
    * @param testObjects Used to create a url.
    */
   

}
